<?php

class userActions extends sfActions {

  public function executeSignup(sfWebRequest $request) {
    if ($this->getUser()->isAuthenticated()) {
      $this->redirect('@home');
    }

    require_once(sfConfig::get('sf_lib_dir') . '/vendor/recaptcha/recaptchalib.php');

    $errorCollector = array();

    $trans = SystemUtil::beginDoctrineTransaction();

    try {
      $this->form = new UserSignupForm();
      if ($request->isMethod('post')) {
        $formData = $request->getParameter(UserSignupForm::FORM_NAME);
        $this->form->bind($formData);

        if ($this->form->isValid()) {
          $user = new USER();
          $user->setUserGroupId(Constants::USER_GROUP_CUSTOMER);
          $user->setFirstName($formData[UserSignupForm::FIELD_FIRST_NAME]);
          $user->setLastName($formData[UserSignupForm::FIELD_LAST_NAME]);
          $user->setUsername($formData[UserSignupForm::FIELD_EMAIL]);
          $user->setEmail($formData[UserSignupForm::FIELD_EMAIL]);
          $salt = StringUtil::generateRandomString(20);
          $user->setSalt($salt);
          $password = StringUtil::hashPassword(trim($formData[UserSignupForm::FIELD_PASSWORD]), $salt);
          $user->setPassword($password);
          if ($formData[UserSignupForm::FIELD_ADDRESS]) {
            $user->setAddress($formData[UserSignupForm::FIELD_ADDRESS]);
          }
          if ($formData[UserSignupForm::FIELD_CITY]) {
            $user->setCity($formData[UserSignupForm::FIELD_CITY]);
          }
          if ($formData[UserSignupForm::FIELD_STATE_ID]) {
            $user->setStateId($formData[UserSignupForm::FIELD_STATE_ID]);
          }
          if ($formData[UserSignupForm::FIELD_POST_CODE]) {
            $user->setPostCode($formData[UserSignupForm::FIELD_POST_CODE]);
          }
          if ($formData[UserSignupForm::FIELD_PHONE]) {
            $user->setPhone($formData[UserSignupForm::FIELD_PHONE]);
          }
          if (isset($formData[UserSignupForm::FIELD_GENDER])) {
            $user->setGender($formData[UserSignupForm::FIELD_GENDER]);
          }
          if ($formData[UserSignupForm::FIELD_DATE_OF_BIRTH]['month'] && $formData[UserSignupForm::FIELD_DATE_OF_BIRTH]['day'] && $formData[UserSignupForm::FIELD_DATE_OF_BIRTH]['year']) {
            $user->setDateOfBirth(date(Constants::DATE_TIME_MYSQL_DB, mktime(1,1,1,$formData[UserSignupForm::FIELD_DATE_OF_BIRTH]['month'],$formData[UserSignupForm::FIELD_DATE_OF_BIRTH]['day'],$formData[UserSignupForm::FIELD_DATE_OF_BIRTH]['year'])));
          }
          if ($formData[UserSignupForm::FIELD_CINEMA]) {
            $user->setPreferenceCinema($formData[UserSignupForm::FIELD_CINEMA]);
          }
          $user->setIpAddress(ServerUtil::getUserIp());
          $user->setType(Constants::USER_TYPE_BASIC_ACCOUNT);
          $user->setIsAlertLaunch((isset($formData[UserSignupForm::FIELD_ALERT_LAUNCH]) ? 1 : 0));
          $user->setIsAlertDeals((isset($formData[UserSignupForm::FIELD_ALERT_DEALS]) ? 1 : 0));
          $user->setStatus(Constants::STATUS_ACTIVE);
          $user->save();
          
          foreach (UserSignupForm::$moviePreferences as $key => $val) {
            if (isset($formData[UserSignupForm::FIELD_MOVIE_PREFERENCE . '_' . $key])) {
              $userMoviePreference = new USER_MOVIE_PREFERENCE();
              $userMoviePreference->setUserId($user->getId());
              $userMoviePreference->setPreference($key);
              $userMoviePreference->save();
            }
          }

          // if user come from order flow, assign ticket to created user
          if ($this->getUser()->hasAttribute(Constants::SESSION_BOOKED_TICKET_ID)) {
            $ticket = TICKETTable::getInstance()->find($this->getUser()->getAttribute(Constants::SESSION_BOOKED_TICKET_ID));
            $ticket->setUserId($user->getId());
            $ticket->save();
            $this->getUser()->getAttributeHolder()->remove(Constants::SESSION_BOOKED_TICKET_ID);
          }

          $email = new EMAIL();
          $email->setEmailTo($user->getEmail());
          $email->setSubject('Welcome to Supertain');
          $email->setMessage(array('name' => $user->getFirstName(), 'username' => $user->getUsername(), 'email' => $user->getEmail(), 'signin_url' => $this->getController()->genUrl('signin', true), 'forgot_url' => $this->getController()->genUrl('forgot', true), 'home_url' => $this->getController()->genUrl('home', true)));
          $email->setTemplateFile('register');
          $email->setContentType(emailTask::CONTENT_TYPE_HTML);
          $email->save();

          SystemUtil::commitDoctrineTransaction($trans);
          $this->redirect('@signup?success=1');
        }
      }
    } catch (Exception $e) {
      $errorCollector[] = LangUtil::getText('error_save_failed');
      SystemUtil::rollbackDoctrineTransaction($trans);
    }
    $this->errorCollector = $errorCollector;
  }

  public function executeSignin(sfWebRequest $request) {
    if ($this->getUser()->isAuthenticated()) {
      $this->redirect('@home');
    }

    $errorCollector = array();
    
    if ($request->hasParameter('fberr')) {
      $errorCollector[] = LangUtil::getText('error_social_signin', array('Facebok'));
    }
    if ($request->hasParameter('twerr')) {
      $errorCollector[] = LangUtil::getText('error_social_signin', array('Twitter'));
    }

    $this->form = new SignInForm(array(Constants::USER_GROUP_CUSTOMER));
    if ($request->isMethod('post')) {
      $formData = $request->getParameter(SignInForm::FORM_NAME);
      $this->form->bind($formData);

      if ($this->form->isValid()) {
        $user = USERTable::getInstance()->findByUsername(trim($formData[SignInForm::FIELD_USERNAME]));
        $user->setIpAddress(ServerUtil::getUserIp());
        $user->setLastLoginAt(date(Constants::DATE_TIME_MYSQL_DB));
        $user->save();

        // if user come from order flow, assign ticket to created user
        if ($this->getUser()->hasAttribute(Constants::SESSION_BOOKED_TICKET_ID)) {
          $ticket = TICKETTable::getInstance()->find($this->getUser()->getAttribute(Constants::SESSION_BOOKED_TICKET_ID));
          $ticket->setUserId($user->getId());
          $ticket->save();
          $this->getUser()->getAttributeHolder()->remove(Constants::SESSION_BOOKED_TICKET_ID);
        }

        $this->getUser()->setAuthenticated(true);
        $this->getUser()->setAttribute(Constants::SESSION_USERNAME, $user->getUsername());
        $this->getUser()->setAttribute(Constants::SESSION_USER_ID, $user->getId());
        $this->getUser()->setAttribute(Constants::SESSION_FIRST_NAME, $user->getFirstName());
        $this->getUser()->setAttribute(Constants::SESSION_LAST_NAME, $user->getLastName());
        $this->getUser()->setAttribute(Constants::SESSION_USER_TYPE, $user->getType());
        $this->getUser()->setAttribute(Constants::SESSION_USER_REG_COMPLETED, $this->isRegistrationCompleted($user));
        $this->getUser()->addCredentials($user->getUSER_GROUP()->getName());
        $this->redirect('@home');
      }
    }

    $twitter = new Twitter(sfConfig::get('app_twitter_consumer_key'), sfConfig::get('app_twitter_consumer_secret'));
    $twitter->setCallbackUrl($this->getController()->genUrl('signin_twitter', true));
    $this->twitterSigninUrl = $twitter->getSigninUrl();

    $facebook = new Facebook(sfConfig::get('app_facebook_app_id'), sfConfig::get('app_facebook_app_secret'));
    $facebook->setCallbackUrl($this->getController()->genUrl('signin_facebook', true));
    $this->facebookSigninUrl = $facebook->getSigninUrl();

    $this->errorCollector = $errorCollector;
  }

  public function executeSignout(sfWebRequest $request) {
    $this->getUser()->setAuthenticated(false);
    $this->getUser()->getAttributeHolder()->remove(Constants::SESSION_USERNAME);
    $this->getUser()->getAttributeHolder()->remove(Constants::SESSION_USER_ID);
    $this->getUser()->getAttributeHolder()->remove(Constants::SESSION_FIRST_NAME);
    $this->getUser()->getAttributeHolder()->remove(Constants::SESSION_LAST_NAME);
    $this->getUser()->getAttributeHolder()->remove(Constants::SESSION_USER_TYPE);
    $this->getUser()->getAttributeHolder()->remove(Constants::SESSION_USER_REG_COMPLETED);
    $this->getUser()->clearCredentials();

    $this->redirect('@home');
  }

  public function executeForgot(sfWebRequest $request) {
    if ($this->getUser()->isAuthenticated()) {
      $this->redirect('@home');
    }
    require_once(sfConfig::get('sf_lib_dir') . '/vendor/recaptcha/recaptchalib.php');
    $errorCollector = array();

    $trans = SystemUtil::beginDoctrineTransaction();

    try {
      $this->form = new ForgotPasswordForm();
      if ($request->isMethod('post')) {
        $formData = $request->getParameter(ForgotPasswordForm::FORM_NAME);
        $this->form->bind($formData);

        if ($this->form->isValid()) {
          $user = USERTable::getInstance()->findByUsername(trim($formData[ForgotPasswordForm::FIELD_USERNAME]));
          $salt = StringUtil::generateRandomString(20);
          $user->setSalt($salt);
          $tmpPassword = StringUtil::generateRandomString(8);
          $password = StringUtil::hashPassword(trim($tmpPassword), $salt);
          $user->setPassword($password);
          $user->save();

          $email = new EMAIL();
          $email->setEmailTo($user->getEmail());
          $email->setSubject('Password Recovery');
          $email->setMessage(array('name' => $user->getFirstName(), 'password' => $tmpPassword, 'url' => $this->getController()->genUrl('signin', true)));
          $email->setTemplateFile('forgotPassword');
          $email->setContentType(emailTask::CONTENT_TYPE_HTML);
          $email->save();

          SystemUtil::commitDoctrineTransaction($trans);
          $this->redirect('@forgot?success=1');
        }
      }
    } catch (Exception $e) {
      $errorCollector[] = LangUtil::getText('error_save_failed');
      SystemUtil::rollbackDoctrineTransaction($trans);
    }
    $this->errorCollector = $errorCollector;
  }

  public function executeTickets(sfWebRequest $request) {
    $pager = new sfDoctrinePager('USER', sfConfig::get('app_list_records_per_page'));
    $pager->setQuery(Doctrine_Query::create()
                      ->from('TICKET t')
                      ->leftJoin('t.OFFER o')
                      ->leftJoin('o.MOVIE m')
                      ->where('t.USER_ID = ?', $this->getUser()->getAttribute(Constants::SESSION_USER_ID))
                      ->andWhere('t.STATUS = ?', Constants::STATUS_PAYMENT_SUCCESS)
                      ->orderBy('t.PAYMENT_DATE desc'));
    $pager->setPage($request->getParameter(sfConfig::get('app_paginator_parameter_name'), 1));
    $pager->init();
    $this->pager = $pager;
  }

  public function executeChangePassword(sfWebRequest $request) {
    $errorCollector = array();

    try {
      $this->form = new ChangePasswordForm();
      if ($request->isMethod('post')) {
        $formData = $request->getParameter(ChangePasswordForm::FORM_NAME);
        $this->form->bind($formData);

        if ($this->form->isValid()) {
          $user = USERTable::getInstance()->find($this->getUser()->getAttribute(Constants::SESSION_USER_ID));
          $salt = StringUtil::generateRandomString(20);
          $password = StringUtil::hashPassword(trim($formData[ChangePasswordForm::FIELD_NEW_PASSWORD]), $salt);
          $user->setPassword($password);
          $user->setSalt($salt);
          $user->save();

          $this->redirect('@change_password?success=1');
        }
      }
    } catch (Exception $e) {
      $errorCollector[] = LangUtil::getText('error_save_failed');
    }

    $this->errorCollector = $errorCollector;
  }

  public function executeSigninFacebook(sfWebRequest $request) {
    if ($this->getUser()->isAuthenticated()) {
      $this->redirect('@home');
    }

    if (!$request->hasParameter('code')) {
      $this->redirect404();
    }
    $facebook = new Facebook(sfConfig::get('app_facebook_app_id'), sfConfig::get('app_facebook_app_secret'));
    $facebook->setCode($request->getParameter('code'));
    $facebook->setCallbackUrl($this->getController()->genUrl('signin_facebook', true));
    $facebook->authorize();

    if(trim($facebook->getAccessToken()) && trim($facebook->getUserId())) {
      $user = USERTable::getInstance()->findByUsername($facebook->getAccessToken());
      if (!is_object($user) || !($user instanceof USER)) {
        $user = new USER();
        $user->setUserGroupId(Constants::USER_GROUP_CUSTOMER);
        $user->setFirstName($facebook->getFirstName());
        $user->setLastName($facebook->getLastName());
        $user->setUsername($facebook->getAccessToken());
        $user->setIpAddress(ServerUtil::getUserIp());
        $user->setType(Constants::USER_TYPE_FACEBOOK_ACCOUNT);
        $user->setStatus(Constants::STATUS_ACTIVE);
        $user->save();
      }

      $user->setIpAddress(ServerUtil::getUserIp());
      $user->setLastLoginAt(date(Constants::DATE_TIME_MYSQL_DB));
      $user->save();

      $this->getUser()->setAuthenticated(true);
      $this->getUser()->setAttribute(Constants::SESSION_USERNAME, $user->getUsername());
      $this->getUser()->setAttribute(Constants::SESSION_USER_ID, $user->getId());
      $this->getUser()->setAttribute(Constants::SESSION_USER_TYPE, $user->getType());
      $this->getUser()->setAttribute(Constants::SESSION_FIRST_NAME, $user->getFirstName());
      $this->getUser()->setAttribute(Constants::SESSION_LAST_NAME, $user->getLastName());
      $this->getUser()->setAttribute(Constants::SESSION_USER_REG_COMPLETED, $this->isRegistrationCompleted($user));
      $this->getUser()->addCredentials($user->getUSER_GROUP()->getName());
    } else {
      SystemUtil::sendAlertEmail('Facebook signin error', 'Access Token: ' . $facebook->getAccessToken() . ' - User ID: ' . $facebook->getUserId());
      $this->redirect('@signin?fberr=1');
    }

    $this->redirect('@home');
  }

  public function executeSigninTwitter(sfWebRequest $request) {
    if ($this->getUser()->isAuthenticated()) {
      $this->redirect('@home');
    }

    if (!$request->hasParameter('oauth_token')) {
      $this->redirect404();
    }
    $twitter = new Twitter(sfConfig::get('app_twitter_consumer_key'), sfConfig::get('app_twitter_consumer_secret'));
    $twitter->setOAuthToken($request->getParameter('oauth_token'));
    $twitter->authorize();

    if(trim($twitter->getOAuthToken()) && trim($twitter->getOAuthTokenSecret()) && trim($twitter->getScreenName())) {
      $user = USERTable::getInstance()->findByUsername($twitter->getOAuthToken());
      if (!is_object($user) || !($user instanceof USER)) {
        $user = new USER();
        $user->setUserGroupId(Constants::USER_GROUP_CUSTOMER);
        $user->setFirstName($twitter->getScreenName());
        $user->setUsername($twitter->getOAuthToken());
        $user->setIpAddress(ServerUtil::getUserIp());
        $user->setType(Constants::USER_TYPE_TWITTER_ACCOUNT);
        $user->setStatus(Constants::STATUS_ACTIVE);
        $user->save();
      }

      $user->setIpAddress(ServerUtil::getUserIp());
      $user->setLastLoginAt(date(Constants::DATE_TIME_MYSQL_DB));
      $user->save();

      $this->getUser()->setAuthenticated(true);
      $this->getUser()->setAttribute(Constants::SESSION_USERNAME, $user->getUsername());
      $this->getUser()->setAttribute(Constants::SESSION_USER_ID, $user->getId());
      $this->getUser()->setAttribute(Constants::SESSION_USER_TYPE, $user->getType());
      $this->getUser()->setAttribute(Constants::SESSION_FIRST_NAME, $user->getFirstName());
      $this->getUser()->setAttribute(Constants::SESSION_LAST_NAME, $user->getLastName());
      $this->getUser()->setAttribute(Constants::SESSION_USER_REG_COMPLETED, $this->isRegistrationCompleted($user));
      $this->getUser()->addCredentials($user->getUSER_GROUP()->getName());
    } else {
      SystemUtil::sendAlertEmail('Twitter signin error', 'OAuth Token: ' . $twitter->getOAuthToken() . ' - OAuth Token Secret: ' . getOAuthTokenSecret . ' - Screen Name: ' . $twitter->getScreenName());
      $this->redirect('@signin?twerr=1');
    }

    $this->redirect('@home');
  }

  public function executeProfileUpdate(sfWebRequest $request) {
    $errorCollector = array();
    try {
      $this->form = new UserSignupForm(true);
      $user = USERTable::getInstance()->find($this->getUser()->getAttribute(Constants::SESSION_USER_ID));
      $this->form->populateData($user);

      if ($request->isMethod('post')) {
        $formData = $request->getParameter(UserSignupForm::FORM_NAME);
        $this->form->bind($formData);

        if ($this->form->isValid()) {
          $user = USERTable::getInstance()->find($this->getUser()->getAttribute(Constants::SESSION_USER_ID));
          $user->setFirstName($formData[UserSignupForm::FIELD_FIRST_NAME]);
          $user->setLastName($formData[UserSignupForm::FIELD_LAST_NAME]);
          $user->setEmail($formData[UserSignupForm::FIELD_EMAIL]);
          if ($formData[UserSignupForm::FIELD_ADDRESS]) {
            $user->setAddress($formData[UserSignupForm::FIELD_ADDRESS]);
          }
          if ($formData[UserSignupForm::FIELD_CITY]) {
            $user->setCity($formData[UserSignupForm::FIELD_CITY]);
          }
          if ($formData[UserSignupForm::FIELD_STATE_ID]) {
            $user->setStateId($formData[UserSignupForm::FIELD_STATE_ID]);
          }
          if ($formData[UserSignupForm::FIELD_POST_CODE]) {
            $user->setPostCode($formData[UserSignupForm::FIELD_POST_CODE]);
          }
          if ($formData[UserSignupForm::FIELD_PHONE]) {
            $user->setPhone($formData[UserSignupForm::FIELD_PHONE]);
          }
          if (isset($formData[UserSignupForm::FIELD_GENDER])) {
            $user->setGender($formData[UserSignupForm::FIELD_GENDER]);
          }
          if ($formData[UserSignupForm::FIELD_DATE_OF_BIRTH]['month'] && $formData[UserSignupForm::FIELD_DATE_OF_BIRTH]['day'] && $formData[UserSignupForm::FIELD_DATE_OF_BIRTH]['year']) {
            $user->setDateOfBirth(date(Constants::DATE_TIME_MYSQL_DB, mktime(1,1,1,$formData[UserSignupForm::FIELD_DATE_OF_BIRTH]['month'],$formData[UserSignupForm::FIELD_DATE_OF_BIRTH]['day'],$formData[UserSignupForm::FIELD_DATE_OF_BIRTH]['year'])));
          }
          if ($formData[UserSignupForm::FIELD_CINEMA]) {
            $user->setPreferenceCinema($formData[UserSignupForm::FIELD_CINEMA]);
          } else {
            $user->setPreferenceCinema(null);
          }
          $user->setIpAddress(ServerUtil::getUserIp());
          $user->save();
          
          foreach (UserSignupForm::$moviePreferences as $key => $val) {
            if (isset($formData[UserSignupForm::FIELD_MOVIE_PREFERENCE . '_' . $key])) {
              $userMoviePreference = new USER_MOVIE_PREFERENCE();
              $userMoviePreference->setUserId($user->getId());
              $userMoviePreference->setPreference($key);
              $userMoviePreference->save();
            } else {
              $userMoviePreference = USER_MOVIE_PREFERENCETable::getInstance()->findByPreference($user->getId(), $key);
              if ($userMoviePreference instanceof USER_MOVIE_PREFERENCE) {
                $userMoviePreference->delete();
              }
            }
          }
          
          $this->getUser()->setAttribute(Constants::SESSION_FIRST_NAME, $user->getFirstName());
          $this->getUser()->setAttribute(Constants::SESSION_LAST_NAME, $user->getLastName());

          if (!$this->getUser()->getAttribute(Constants::SESSION_USER_REG_COMPLETED)) {
            $this->getUser()->setAttribute(Constants::SESSION_USER_REG_COMPLETED, true);
          }

          $this->redirect('@profile_update?success=1');
        }
      }
    } catch (Exception $e) {
      $errorCollector[] = LangUtil::getText('error_save_failed');
    }

    $this->errorCollector = $errorCollector;
  }

  private function isRegistrationCompleted(USER $user) {
    $email = $user->getEmail();
    $fname = $user->getFirstName();

    if (!empty ($email) && !empty ($fname)) {
      return true;
    }
    return false;
  }
}